package com.voice.call.service.impl;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.UUID;

import javax.annotation.Resource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import voice.voice.call.cache.ConfigSystemCache;

import com.voice.call.common.Const;
import com.voice.call.common.Result;
import com.voice.call.common.ResultEnum;
import com.voice.call.entity.InviteCode;
import com.voice.call.entity.InviteLog;
import com.voice.call.mapper.InviteCodeMapper;
import com.voice.call.service.ConsumeLogService;
import com.voice.call.service.InviteCodeService;
import com.voice.call.service.InviteLogService;
import com.voice.call.service.SupportMccService;
//import com.voice.call.service.TaskLogService;
import com.voice.call.service.UserAccountService;
import com.voice.call.utils.StringUtil;

@Service
public class InviteCodeServiceImpl implements InviteCodeService{
	
	private static final Logger log = LoggerFactory.getLogger(InviteCodeServiceImpl.class);
	
	private static final Random RND = new Random(UUID.randomUUID().hashCode());
	private static final char[] charsNumLets = new char[] {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'};
	
	@Resource
	private InviteCodeMapper inviteCodeMapper;
	
	@Resource
	private InviteLogService inviteLogService;
	
	//@Resource
	//private TaskLogService taskLogService;
	
	//@Resource
	//private TaskIntegralService taskIntegralService;
	
	@Resource
	private UserAccountService userAccountService;
	
	@Resource
	private ConsumeLogService consumeLogService;
	
	@Resource
	private ConfigSystemCache configSystemCache;
	
	@Resource
	private SupportMccService supportMccService;

	//获取用户邀请码
	@Override
	public 	String getUserInviteCode(Integer user_id){
		
		Map<String, Object> paramsMap = new HashMap<String, Object>();
		paramsMap.put("userId", user_id);
		paramsMap.put("status", Const.Y);
		List<InviteCode> list = inviteCodeMapper.list(paramsMap);
		if(list!=null && !list.isEmpty()){
			log.info("当前有可用的邀请码");
			return list.get(0).getCode();
		}
		
		InviteCode entity = new InviteCode();
		entity.setUserId(user_id);
		entity.setCode(createVertifyCode());
		entity.setStatus(Const.Y);
		entity.setCtime(new Date());
		entity.setMtime(new Date());
		
		if(inviteCodeMapper.insert(entity) >0){
			log.info("生成邀请码成功");
			return entity.getCode();
		}
		log.error("生成邀请码失败");
		return null;
	}
	
	/**
	 * 邀请码验证
	 * @param user_id 被邀请人
	 * @param code    邀请码
	 * @return
	 */
	@Transactional
	@Override
	public Result verifyCode(Integer user_id,String code,String ip){
		
		try {
			
			if(!supportMccService.isSupportCountry(ip)){
				log.info("非支持国家签到");
				return new Result(ResultEnum.ILLEGAL_INTERVAL_ERROR);
			}
			
			InviteCode entity = this.findByCode(code);
			if(entity==null){
				return new Result(ResultEnum.INVITE_CODE_ERROR);
			}
			if (entity.getUserId().equals(user_id)) { //不能自已邀请自已
				
				return new Result(ResultEnum.INVITE_USER_SELF_ERROR);
			}
			
			if(entity.getStatus().equals(Const.N)){
				return new Result(ResultEnum.INVITE_CODE_EXPRIED);
			}
			//1.用户已被邀请过
			if(inviteLogService.existsInvite(user_id)){
				return new Result(ResultEnum.USER_EXISTS_INVITE);
			}
			//2.修改邀请码状态，添加邀请记录
			InviteCode updateEntity = new InviteCode();
			updateEntity.setId(entity.getId());
			updateEntity.setStatus(Const.N);
			updateEntity.setCtime(new Date());
			if (inviteCodeMapper.update(updateEntity)>0) {
				log.info("更新状态成功");
			}else {
				log.error("更新状态失败!");
				return new Result(ResultEnum.FAILED);
			}
			//3.添加记录
			if (inviteLogService.addInviteLog(entity.getUserId(), user_id,entity.getId())) {
				log.info("添加邀请记录成功");
			}else {
				log.error("添加邀请记录失败");
				return new Result(ResultEnum.FAILED);
			}
			
			Map<String, Object> rsMap = new HashMap<String, Object>();
			
			if(supportMccService.isSupportCountry(ip)){
				 //4.1 邀请人添加积分
				StringBuilder sbIntegral = new StringBuilder("");
				if(consumeLogService.addCategoryConsumeLog(Const.TASK_INVITE, ip, entity.getUserId(), "invite", true, null, sbIntegral)){
					if (sbIntegral.length()>0) {
						rsMap.put("integral", sbIntegral);
					}
				}
				//4.2 被邀请人添加积分
				if(consumeLogService.addCategoryConsumeLog(Const.TASK_INVITE, ip, user_id, "invite", true, null, null)){
					log.info("被邀请人添加积分成功");
				}else {
					log.error("被邀请人添加积分失败");
				}
				//5.获取额外邀请积分
				this.extraInvite(entity.getUserId());
			}else{
				log.info("不支持注册国家，填写邀请码,不送积分");
			}
			
			
			if (!rsMap.isEmpty()) {
				return new Result(rsMap);
			}
			
			return new Result();
			
		} catch (Exception e) {
			e.printStackTrace();
			log.error("邀请码验证，发生异常");
			return new Result(ResultEnum.SYSTEM_ERROR);
		}
		
	}
	
	//额外邀请处理
	@Transactional
	private boolean extraInvite(Integer user_id) {
		String extraIntegral = configSystemCache.get(Const.TASK_INVITE_EXTRA);
		if(StringUtil.isEmpty(extraIntegral)){
			log.error("未配置额外邀请积分值");
			return false; 
		}
		Integer integral = Integer.valueOf(extraIntegral);
		//取得上级邀请人
		InviteLog inviteLog = inviteLogService.getUpperInviteUser(user_id);
		if(inviteLog ==null){
			log.error("不存在上级邀请人");
			return false;
		}
		
		//判断是否已经超过额外限制
		String limit = configSystemCache.get(Const.SYSTEM_INVITE_LIMIT);
		if(limit!=null){
			int limitValue = Integer.valueOf(limit).intValue();
			if(limitValue==0){
				log.info("当前已被限制额外邀请积分");
				return false;
			}else if(limitValue>0){
				//获取总数
				int total = inviteLogService.inviteCount(user_id);
				if (total>limitValue) {
					log.info("超过最大额外邀请积分数");
					return false;
				}
				
			}
		}
		
		
		//1. 被邀请人添加积分
		if(userAccountService.updateAccountBlance(inviteLog.getUserId(), integral, true)){
			log.info("被邀请人添加积分成功");
		}else {
			log.error("被邀请人添加积分失败");
		}
		//2. 添加消费记录
		if(consumeLogService.addConsumeLog(inviteLog.getUserId(), Const.TASK_INVITE, Const.TASK_INVITE,integral,true, null)){
			log.info("被邀请人添加消费记录成功");
		}else {
			log.error("被邀请人添加消费记录失败");
		}
		
		return true;
	}
	
	@Override
	public InviteCode findByCode(String code){
		
		Map<String, Object> paramsMap = new HashMap<String, Object>();
		paramsMap.put("code", code);
		return inviteCodeMapper.getOne(paramsMap);
	}
	
	private String createVertifyCode(){
		
		String code = this.getRandomVertifyCode(8);
		
		InviteCode entity = this.findByCode(code);
		if(entity!=null){
			return createVertifyCode();
		}
		return code;
	}
	
	/**
	 * 生成len长度的随机数验证码
	 * @param len 长度
	 * @return 随机数字符
	 */
	private  String getRandomVertifyCode(int len){
		StringBuilder sb = new StringBuilder();
		for (int i = 0; i < len; i++) {
			sb.append(charsNumLets[RND.nextInt(charsNumLets.length)]);
		}
		return sb.toString();
	}
}
